<?php

namespace JsonLowCode;

use Closure;
use JsonLowCode\Support\Fluent;
use JsonLowCode\Traits\HasMake;

class Content extends Fluent
{
    use HasMake;

    protected array $packages;
    protected array $maps;

    public function __construct(UI\Page|Closure $args = null)
    {
        parent::__construct();
        if ($args!=null){
            if ($args instanceof UI\Page){
                $this->schema($args);
            }
            if ($args instanceof Closure){
                call_user_func($args, $this);
            }
        }
    }

    /**
     * 组件结构数据
     * @param Schema $schema
     * @return $this
     */
    public function schema(Schema $schema): static
    {
        $this->attributes['schema'] = $schema;
        return $this;
    }

    /**
     * 脚本js加载包
     * @param array<int,Package|array> $packages
     * @return $this
     */
    public function packages(array $packages): static
    {
        $this->attributes['packages'] = $packages;
        return $this;
    }

    /**
     * 脚本js加载包
     * @param array|Package $package
     * @return $this
     */
    public function package(array|Package $package): static
    {
        $this->attributes['packages'][] = $package;
        return $this;
    }

    /**
     * 组件注册与映射
     * @param array $maps
     * @return $this
     */
    public function maps(array $maps): static
    {
        $this->attributes['maps'] = array_merge($this->attributes['maps']??[],$maps);
        return $this;
    }

    /**
     * 组件注册与映射
     * @param callable|null $callback
     * @return Map
     */
    public function map(callable $callback = null): Map
    {
        $map = new Map();
        if ($callback!=null){
            $callback($map);
        }
        $this->attributes['maps'][] = $map;
        return $map;
    }

    /**
     * package= 包组件映射
     * @param string $package 包名
     * @param string $version 包版本
     * @param string $componentName 组件名称
     * @param string $exportName 导出名称
     * @param callable|null $callback
     * @return Map
     */
    public function mapPackage(string $package, string $version,string $componentName,string $exportName = "",callable $callback = null): Map
    {
        $map = new Map(['type'=>'tpl']);
        $map->package($package, $version, $componentName, $exportName);
        if ($callback!=null){
            $callback($map);
        }
        $this->attributes['maps'][] = $map;
        return $map;
    }

    public function jsonSerialize():array
    {
        $maps = UI::getMaps();
        $this->maps($maps);
        $blocksData = UI::getDefineBlock();
        $this->attributes['blocksData'] = $blocksData;
        $this->attributes['componentsMap'] = array_map(function ($item){
            return [
                'componentName'=>$item['label'],
                'main'=>'components'
            ];
        },$blocksData);
        return parent::jsonSerialize();
    }


}
